package controllers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.sql.Date;

import javax.swing.JOptionPane;

import common.Perror;

import client.ChatClient;

import GUI.*;
import GUI.lecturerGUI.*;

import MsgPackage.*;
import ReportHistogram.ReportHistogram;
import entities.*;

public class LecturerController {
	private LecturerQuestions lecturerQuestionGUI;
	private LecturerWindow lecturerWindowGUI;

	private LecturerReportFile LecturerReportFileGUI;
	private LecturerExam lecturerExamGUI;
	private LecturerDurationTimeRequest lecturerDurationGUI;
	private LecturerGenerateExamCode lecturerGenerateExamCodeGUI;
	private LecturerReports lecturerReportsGUI;
	private LecturerCheckGrade lecturerCheckGradeGUI;
	private ChatClient client;
	private MainGUI mainGUI;
	final public static int EXIT = 1; // Quit to login menu.
	final public static int MAIN = 2; // Return to Lecturer Window.
	final public static int REPORT = 3; // Open Lecturer Reports
	final public static int NEWEXAM = 4; // Open Lecturer Exam window
	final public static int NEWQUESTION = 5; // Open Lecturer Question
	final public static int ADDDURESTION = 10; // Open Lecturer Duration
	final public static int EXTRACTEXAM = 13; // Open Lecturer Generate exam
	final public static int APPROVEGRADES = 9; // open approve grades window

	final public static int REPORTFILE = 6;
	public static final int HISTOGRAM = 0;

	private Lecturer lctrr;
/**
 * 	handle Lecturer  GUI Operation
 * @param client 
 * @param mainframe - the main frame
 */
	public LecturerController(ChatClient client, MainGUI mainframe) {
		this.client = client;
		this.mainGUI = mainframe;
		mainGUI.setSize(MainGUI.setX, MainGUI.setY);
		lecturerWindowGUI = new LecturerWindow(this);
		mainGUI.setContentPane(lecturerWindowGUI);
		if (lctrr == null) {
			lctrr = new Lecturer();
			lctrr.setID(MainGUI.lgnUsr.getUserID());
		}
		getUnlockedExams();
	}
/**
 * 	handle Lecturer  GUI Operation 
 * @param operation -Operation the teacher wants to do
 */
	public void handleLectutereGUI(int operation) {
		lecturerWindowGUI.cleanExams();
		GetLecturerSubjectPack lctrrSbjMsg;
		switch (operation) {	
		case EXIT:// logout
			lctrr = null;
			mainGUI.returnToLogin();
			break;

		case MAIN:// back main
			if (lecturerWindowGUI == null)
				lecturerWindowGUI = new LecturerWindow(this);
			  LecturerReportFileGUI = null;
			  lecturerExamGUI = null;
			  lecturerDurationGUI = null;
			  lecturerGenerateExamCodeGUI = null;
			  lecturerReportsGUI = null;
			  lecturerCheckGradeGUI = null;
			mainGUI.setContentPane(lecturerWindowGUI);
			getUnlockedExams();
			break;

		case NEWEXAM: // new exam window
			if (lecturerExamGUI == null)
				lecturerExamGUI = new LecturerExam(this);
			mainGUI.setContentPane(lecturerExamGUI);
			lctrrSbjMsg = new GetLecturerSubjectPack(lctrr);
			client.handleMessageFromClientUI(lctrrSbjMsg);
			lctrrSbjMsg = (GetLecturerSubjectPack) client.getMessage();
			lecturerExamGUI.addSubjects(lctrrSbjMsg.getSbj());
			break;

		case ADDDURESTION:// add duration window
			if (lecturerDurationGUI == null)
				lecturerDurationGUI = new LecturerDurationTimeRequest(this);
			mainGUI.setContentPane(lecturerDurationGUI);

			GetActiveExamsPack actvExamsMsg = new GetActiveExamsPack(lctrr);
			client.handleMessageFromClientUI(actvExamsMsg);
			actvExamsMsg = (GetActiveExamsPack) client.getMessage();
			lecturerDurationGUI.addActiveExams(actvExamsMsg.getActiveExams());
			break;

		case REPORT:// report window
			if (lecturerReportsGUI == null)
				lecturerReportsGUI = new LecturerReports(this);

			GetReport();
			mainGUI.setContentPane(lecturerReportsGUI);
			break;

		case NEWQUESTION:// question window
			if (lecturerQuestionGUI == null)
				lecturerQuestionGUI = new LecturerQuestions(this);
			mainGUI.setContentPane(lecturerQuestionGUI);
			lctrrSbjMsg = new GetLecturerSubjectPack(lctrr);

			client.handleMessageFromClientUI(lctrrSbjMsg);
			lctrrSbjMsg = (GetLecturerSubjectPack) client.getMessage();
			lecturerQuestionGUI.addSubjects(lctrrSbjMsg.getSbj());
			break;

		case EXTRACTEXAM:// EXTRACTE EXAM WINDOW
			if (lecturerGenerateExamCodeGUI == null)
				lecturerGenerateExamCodeGUI = new LecturerGenerateExamCode(this);

			GetExamsToExtractPack lctrrexmMsg = new GetExamsToExtractPack(lctrr);
			client.handleMessageFromClientUI(lctrrexmMsg);
			lctrrexmMsg = (GetExamsToExtractPack) client.getMessage();
			lecturerGenerateExamCodeGUI.addExams(lctrrexmMsg.GetExam());
			mainGUI.setContentPane(lecturerGenerateExamCodeGUI);

			break;

		case APPROVEGRADES:
			if (lecturerCheckGradeGUI == null)
				lecturerCheckGradeGUI = new LecturerCheckGrade(this);
			GetUnapprovedExamsPack unaprvdExmspck = new GetUnapprovedExamsPack(
					lctrr);
			client.handleMessageFromClientUI(unaprvdExmspck);
			unaprvdExmspck = (GetUnapprovedExamsPack) client.getMessage();
			mainGUI.setContentPane(lecturerCheckGradeGUI);
			lecturerCheckGradeGUI.addExamsCodes(unaprvdExmspck
					.getExtractedExamsList());
			break;
		case REPORTFILE:
			if (LecturerReportFileGUI == null)
				LecturerReportFileGUI = new LecturerReportFile(this);
			mainGUI.setContentPane(LecturerReportFileGUI);
			break;
		}
	}
/**
 * get the report the lecturer want 
 * @return send the lecturer report  
 * @param examcode -exam code
 */
	
	public void GetReportFile(ExtractedExam extexm) {
		LecturerReportFilePack lrfmsg = new LecturerReportFilePack(extexm);
		client.handleMessageFromClientUI(lrfmsg);

		lrfmsg = (LecturerReportFilePack) client.getMessage();
		extexm.getExamCode();
		handleLectutereGUI(REPORTFILE);
		LecturerReportFileGUI.setExam(lrfmsg.getGrades(), extexm);
	}

/**
 *get from the server the reports of the lecturer   
 */
	public void GetReport() {
		ArrayList<ExtractedExam> arry = new ArrayList<ExtractedExam>();
		LecturerReportPack lctrrRptMsg = new LecturerReportPack(lctrr);
		client.handleMessageFromClientUI(lctrrRptMsg);
		lctrrRptMsg = (LecturerReportPack) client.getMessage();
		// LecturerReportsGUI
		arry = lctrrRptMsg.GetReport();
		lecturerReportsGUI.addReport(arry);
	}

	
	/**
	 * generate the exam code for the lecturer selectedExam 
	 * @param selectedExam -the lecturer selected exam 
	 */
	public void GenerateExamCode(ExtractedExam selectedExam) {
		ExtractExamPack lctrrexamMsg = new ExtractExamPack(lctrr);
		lctrrexamMsg.setExam(selectedExam);
		client.handleMessageFromClientUI(lctrrexamMsg);
		JOptionPane.showMessageDialog(MainGUI.mainframe,
				(String) client.getMessage());
	}
/**
 * 
 * @param courseNum
 * @param subjectNum
 * @return  the_exam 
 * 
 */
	public Integer getNewExamID(Integer courseNum, Integer subjectNum) {
		GetExamNumberPack getEnumPck = new GetExamNumberPack(courseNum,
				subjectNum);
		client.handleMessageFromClientUI(getEnumPck);
		getEnumPck = (GetExamNumberPack) client.getMessage();
		return getEnumPck.getNewExamNum();
	}

	public Integer getNewQuestionID(Integer courseNum) {
		GetQuestionNumberPack getQnumPck = new GetQuestionNumberPack(courseNum);
		client.handleMessageFromClientUI(getQnumPck);
		getQnumPck = (GetQuestionNumberPack) client.getMessage();
		return getQnumPck.getNewQuestionNum();

	}
/**
 *  lecturer create new question for exam  
 */
	public void CreateNewQuestion() {

		Question qstn = new Question();

		qstn.setqID(lecturerQuestionGUI.getID());
		qstn.setqText(lecturerQuestionGUI.getQuestionText());
		qstn.setqDate(Calendar.getInstance().getTime());
		qstn.setqCreator(MainGUI.lgnUsr.getUserID());

		qstn.setqInstructions(lecturerQuestionGUI.getInsructions());
		qstn.setCorrectAns(lecturerQuestionGUI.getCorrectAnswer());
		qstn.setAnswerA(lecturerQuestionGUI.getAnswerA());
		qstn.setAnswerB(lecturerQuestionGUI.getAnswerB());
		qstn.setAnswerC(lecturerQuestionGUI.getAnswerC());
		qstn.setSubjectID(lecturerQuestionGUI.getSubjectID());

		AddQuestionPack qstnMsg = new AddQuestionPack(qstn);
		client.handleMessageFromClientUI(qstnMsg);
		qstnMsg = (AddQuestionPack) client.getMessage();
		if (qstnMsg.getQuestion().getqID().equals(Question.ERROR))
			common.Perror.pError("Unable to add question");
		else {
			if (qstnMsg.getQuestion().getqID()
					.equals(lecturerQuestionGUI.getID()))
				JOptionPane.showMessageDialog(mainGUI,
						"Question added successfully");
			else
				JOptionPane.showMessageDialog(mainGUI,
						"Question ID has been changed to "
								+ qstnMsg.getQuestion().getqID());
			lecturerQuestionGUI.cleanLecturerQuestionGUI();
		}
	}
/**
 * set Courses Per Subject
 * @param selectedSubject
 */

	public void setCoursesPerSubject(Subject selectedSubject) {
		ArrayList<Course> courses = new ArrayList<Course>();
		GetCoursesPerSubjectPack crssPerSbj = new GetCoursesPerSubjectPack(
				selectedSubject);
		GetLecturerCoursesPack crssPerLec = new GetLecturerCoursesPack(lctrr);
		client.handleMessageFromClientUI(crssPerSbj);
		crssPerSbj = (GetCoursesPerSubjectPack) client.getMessage();
		client.handleMessageFromClientUI(crssPerLec);
		crssPerLec = (GetLecturerCoursesPack) client.getMessage();
		for (int i = 0; i<crssPerSbj.getLstCrs().size(); i++)
			for (int j = 0; j<crssPerLec.getCrs().size(); j++)
				if (crssPerSbj.getLstCrs().get(i).getCourseID().equals(crssPerLec.getCrs(j).getCourseID()))
					courses.add(crssPerLec.getCrs(j));
		lecturerExamGUI.addCourses(courses);

	}
/* *
 * 
 */
	public void setQuestionsPerSubject(Subject selectedSubject) {
		GetQuestionsPerSubjectPack crssPerSbj = new GetQuestionsPerSubjectPack(
				selectedSubject);
		client.handleMessageFromClientUI(crssPerSbj);
		crssPerSbj = (GetQuestionsPerSubjectPack) client.getMessage();
		lecturerExamGUI.addQuestions(crssPerSbj.getLstQst());

	}
/**
 * lecturer  create and save new exam 
 */
	public void createNewExam() {
		AddExamPack newExmPxk = new AddExamPack();
		Exam exm = new Exam();
		exm.setCourseID((lecturerExamGUI.getSelectedCourse().getCourseID()));
		exm.setSubjectID((lecturerExamGUI.getSelectedSubject().getSubjectID()));
		exm.setExamID(lecturerExamGUI.getExamID());
		exm.setExamCreationDate(new Date(Calendar.getInstance()
				.getTimeInMillis()));
		exm.setExamLecturerID(lctrr.getID());
		exm.setExamDurationTime(lecturerExamGUI.getDurationTime());
		exm.setExamLecturerInstructions(lecturerExamGUI.getLecturerComment());
		exm.setExamStudentInstructions(lecturerExamGUI.getStudentComment());
		exm.addQuestion(lecturerExamGUI.getExamQuestions());

		newExmPxk.setExm(exm);

		client.handleMessageFromClientUI(newExmPxk);
		newExmPxk = (AddExamPack) client.getMessage();
		if (newExmPxk.getExm().getExamID() == Exam.ERROR)
			common.Perror.pError("Unable to add exam");
		else {
			if (lecturerExamGUI.getExamID().equals(
					newExmPxk.getExm().getExamID()))
				JOptionPane.showMessageDialog(mainGUI,
						"Exam added successfully");
			else
				JOptionPane.showMessageDialog(mainGUI,
						"Exam ID has been changed to "
								+ newExmPxk.getExm().getExamID());
			lecturerExamGUI.RestoreToDefualt();
		}
	}

	/**
	 * the lecturer get the list of unlock exam
	 */
	
	public void getUnlockedExams() {
		GetUnlockedExamsPack unlckdExms = new GetUnlockedExamsPack(lctrr);
		client.handleMessageFromClientUI(unlckdExms);
		unlckdExms = (GetUnlockedExamsPack) client.getMessage();
		lecturerWindowGUI.addExams(unlckdExms.getExtractedExamsList());
	}
/**
 * lecturer lock the exam 
 * @param exm - the exam to lock
 */ 
	public void lockExam(ExtractedExam exm) {
		LockExamPack lckExm = new LockExamPack(exm);
		client.handleMessageFromClientUI(lckExm);
		lckExm = (LockExamPack) client.getMessage();
		exm = lckExm.getExtExm();
		if (exm.getLockedExam() != ExtractedExam.STATUS_ACTIVE) {
			JOptionPane.showMessageDialog(mainGUI, "Exam has been locked");
			lecturerWindowGUI.removeExam();
		} else
			JOptionPane.showMessageDialog(mainGUI, "Exam was not locked");
	}
/**
 *get the list of exams which the lecturer can ask for approval of additional time  
 */
	public void getExamsToApprove(ExtractedExam selectedExam) {
		GetExamsToApprovePack exmToApprve = new GetExamsToApprovePack(
				selectedExam);
		client.handleMessageFromClientUI(exmToApprve);
		exmToApprve = (GetExamsToApprovePack) client.getMessage();
		lecturerCheckGradeGUI.addQuestions(exmToApprve.getQuestions());
		lecturerCheckGradeGUI.addExams(exmToApprve.getComputerizedExams());

	}
/*
 * if the request  been approve
 */
	public boolean approveGrade(ComputerizedExam compExm) {
		ApproveGradePack appGradePck = new ApproveGradePack(compExm);
		client.handleMessageFromClientUI(appGradePck);
		appGradePck = (ApproveGradePack) client.getMessage();
		if (!(appGradePck.getCmptExam().getExamApproved())) {
			Perror.pError("Exam couldn't be approve at this moment, \nplease contact you server administrator.");
			return false;
		}
		return true;
	}
/*
 * lecturer send approve time request to principal
 */
	public void addDurationTimeRequest() {
		Request rqst = new Request();
		rqst.setApproved(Request.WAITING);
		rqst.setExamCode(lecturerDurationGUI.getCode());
		rqst.setExtensionDurationTime(lecturerDurationGUI.getTime());
		rqst.setCreatorId(MainGUI.lgnUsr.getUserID());
		rqst.setReasons(lecturerDurationGUI.getReasons());
		AddDurationTimePack addDrtnTmPck = new AddDurationTimePack(rqst);
		client.handleMessageFromClientUI(addDrtnTmPck);
		addDrtnTmPck = (AddDurationTimePack) client.getMessage();
		if (addDrtnTmPck.getRqst().getExtensionDurationTime() > 0) {
			JOptionPane.showMessageDialog(mainGUI, "Request sent");
			lecturerDurationGUI.removeExam();
		} else
			JOptionPane.showMessageDialog(mainGUI, "Request failed");
	}

	public void cheatAlart() {
		JOptionPane
				.showMessageDialog(mainGUI,
						"Please notice, System suspect exams to be copied.\n marked with '*'");

	}
	



}
